<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 判断数据类型方法

      function getType(typeObj) {
        return Object.prototype.toString.call(typeObj).slice(8, -1);
      }

      // 深拷贝
      function cloneDeep(obj, map = new Map()) {
        // 先判断是否是数组或者对象，否则直接返回
        let type = getType(obj);
        if (type === "Object" || type === "Array") {
          //声明一个克隆的容器对象
          let cloneObj = map.get(obj);

          if (cloneObj) return cloneObj;

          // 判断是对象
          if (type === "Object") {
            // 创建一个空对象
            cloneObj = {};
            map.set(obj, cloneObj);
            Object.keys(obj).forEach((item) => {
              cloneObj[item] = cloneDeep(obj[item], map);
            });
          } else {
            cloneObj = [];
            map.set(obj, cloneObj);
            obj.forEach((item, index) => {
              cloneObj[index] = cloneDeep(item, map);
            });
          }
          return cloneObj;
        } else {
          return obj;
        }
      }

      let obj1 = {
        a: { b: 1 },
        b: [2, 3],
        c: {
          a: {
            b: [4, 6],
          },
        },
      };

      obj1.c.a.b = obj1.a;
      obj1.a.b = obj1.c;

      let obj2 = cloneDeep(obj1);
      console.log(obj2);
    </script>
  </body>
</html>
